import getClientSize from './getClientSize.js';
const ellArr = [
    { class: '.ell-l', type: 'left' },
    { class: '.ell-r', type: 'right' },
    { class: '.ell-t', type: 'top' },
    { class: '.ell-b', type: 'bottom' },
];
const ellAlwaysArr = [
    { class: '.ell-a-l', type: 'left' },
    { class: '.ell-a-r', type: 'right' },
    { class: '.ell-a-t', type: 'top' },
    { class: '.ell-a-b', type: 'bottom' },
];
const ellMultipleArr = [
    { class: '.ell-m-l', type: 'left' },
    { class: '.ell-m-r', type: 'right' },
    { class: '.ell-m-t', type: 'top' },
    { class: '.ell-m-b', type: 'bottom' },
    // 用于兼容上个版本的命名
    { class: '.elln-l', type: 'left' },
    { class: '.elln-r', type: 'right' },
    { class: '.elln-t', type: 'top' },
    { class: '.elln-b', type: 'bottom' },
];
function setEllItem(dom, type) {
    const padding = 5; //定义弹框距边界的位置
    const anglePadding = 9; //定义小三角距边界的位置，padding加上圆角尺寸
    // 获取dom的尺寸
    const { innerText, clientWidth, clientHeight } = dom;
    const { w, h } = getClientSize(); //浏览器可见区域高宽尺寸
    const { left, top, bottom, right } = dom.getClientRects()[0];
    let content = dom.getAttribute('ell-value');
    if (!content) {
        if (innerText) {
            content = innerText;
            dom.setAttribute('ell-value', content);
        }
        else {
            return;
        }
    }
    // 获取目标dom的style并封装成对象，便于修改
    let cssTextArr = dom.style.cssText.split(';');
    let cssObj = {};
    cssTextArr.forEach((item) => {
        let arr = item.split(':');
        cssObj[arr[0]] = arr[1];
    });
    //获取ell:after的尺寸
    let afterDom = window.getComputedStyle(dom, ':after');
    let afterWidth = parseInt(afterDom.width);
    let afterMaxWidth = parseInt(window.getComputedStyle(document.documentElement).getPropertyValue('--ell-max-width'));
    if (afterWidth >= afterMaxWidth) {
        cssObj['--ell-wrap'] = 'pre-wrap';
        cssObj['--ell-min-width'] = afterMaxWidth;
        cssObj['--ell-width'] = afterMaxWidth;
    }
    else {
        cssObj['--ell-wrap'] = 'nowrap';
        cssObj['--ell-width'] = afterDom.width;
    }
    let cssString = '';
    for (let key in cssObj) {
        cssString += key + ':' + cssObj[key] + ';';
    }
    dom.style.cssText = cssString;
    // return
    afterDom = window.getComputedStyle(dom, ':after');
    var { paddingBottom, paddingLeft, paddingRight, paddingTop, height, width, borderWidth } = afterDom;
    let obj = {
        paddingBottom,
        paddingLeft,
        paddingRight,
        paddingTop,
        height,
        width,
        borderWidth,
    };
    for (let key in obj) {
        obj[key] = parseInt(obj[key]);
    }
    var { paddingBottom, paddingLeft, paddingRight, paddingTop, height, width, borderWidth } = obj;
    borderWidth = borderWidth || 0; //在firefox中为空字符串，parseInt后为NaN
    const afterDomOffsetWidth = width + paddingLeft + paddingRight + borderWidth * 2;
    const afterDomOffsetHeight = height + paddingTop + paddingBottom + borderWidth * 2;
    //获取ell:before，即气泡框上的小三角的尺寸
    const beforeDom = window.getComputedStyle(dom, ':before');
    const beforeDomWidth = parseInt(beforeDom.width) + 2 * parseInt(beforeDom.borderWidth);
    // 根据上一步获取的尺寸，计算ell堤示框能否在视野内完全显示，若不能，强制更换其显示位置
    if (left - afterDomOffsetWidth - beforeDomWidth < 0 && type === 'left')
        type = 'right';
    if (right + afterDomOffsetWidth + beforeDomWidth > w && type === 'right')
        type = 'left';
    if (top - afterDomOffsetHeight - beforeDomWidth < 0 && type === 'top')
        type = 'bottom';
    if (bottom + afterDomOffsetHeight + beforeDomWidth > h && type === 'bottom')
        type = 'top';
    //根据ell位置，给style对象设置新值
    let ellLeft = padding;
    let ellTop = padding;
    let angleTop = anglePadding;
    switch (type) {
        case 'top':
            ellLeft = left - (afterDomOffsetWidth - clientWidth) / 2;
            ellLeft = Math.max(ellLeft, padding);
            ellLeft = Math.min(ellLeft, w - afterDomOffsetWidth - padding);
            cssObj['--ell-left'] = `${ellLeft}px`;
            cssObj['--ell-top'] = `${top - afterDomOffsetHeight - (beforeDomWidth / 2) * Math.sqrt(2)}px`;
            cssObj['--ell-angle-left'] = `${left + clientWidth / 2 - beforeDomWidth / 2}px`;
            cssObj['--ell-angle-top'] = `${top - beforeDomWidth - (beforeDomWidth / 2) * (Math.sqrt(2) - 1)}px`;
            break;
        case 'bottom':
            ellLeft = left - (afterDomOffsetWidth - clientWidth) / 2;
            ellLeft = Math.max(ellLeft, padding);
            ellLeft = Math.min(ellLeft, w - afterDomOffsetWidth - padding);
            cssObj['--ell-left'] = `${ellLeft}px`;
            cssObj['--ell-top'] = `${bottom + (beforeDomWidth / 2) * Math.sqrt(2)}px`;
            cssObj['--ell-angle-left'] = `${left + clientWidth / 2 - beforeDomWidth / 2}px`;
            cssObj['--ell-angle-top'] = `${bottom + (beforeDomWidth / 2) * (Math.sqrt(2) - 1)}px`;
            break;
        case 'right':
            ellTop = top - (afterDomOffsetHeight - clientHeight) / 2;
            ellTop = Math.max(ellTop, padding);
            ellTop = Math.min(ellTop, h - afterDomOffsetHeight - padding);
            angleTop = top + (clientHeight - beforeDomWidth) / 2;
            angleTop = Math.max(angleTop, anglePadding);
            angleTop = Math.min(angleTop, h - beforeDomWidth * 2 - anglePadding);
            cssObj['--ell-left'] = `${right + (beforeDomWidth / 2) * Math.sqrt(2)}px`;
            cssObj['--ell-top'] = `${ellTop}px`;
            cssObj['--ell-angle-left'] = `${right + (beforeDomWidth / 2) * (Math.sqrt(2) - 1)}px`;
            cssObj['--ell-angle-top'] = `${angleTop}px`;
            break;
        case 'left':
            ellTop = top - (afterDomOffsetHeight - clientHeight) / 2;
            ellTop = Math.max(ellTop, padding);
            ellTop = Math.min(ellTop, h - afterDomOffsetHeight - padding);
            angleTop = top + (clientHeight - beforeDomWidth) / 2;
            angleTop = Math.max(angleTop, anglePadding);
            angleTop = Math.min(angleTop, h - beforeDomWidth * 2 - anglePadding);
            cssObj['--ell-left'] = `${left - afterDomOffsetWidth - (beforeDomWidth / 2) * Math.sqrt(2)}px`;
            cssObj['--ell-top'] = `${ellTop}px`;
            cssObj['--ell-angle-left'] = `${left - beforeDomWidth - (beforeDomWidth / 2) * (Math.sqrt(2) - 1)}px`;
            cssObj['--ell-angle-top'] = `${angleTop}px`;
            break;
        default:
            break;
    }
    //将新的style对象重新拼接成字符串
    let cssTextString = '';
    for (let key in cssObj) {
        cssTextString += key + ':' + cssObj[key] + ';';
    }
    let tooltip = document.getElementById('simply-ellipsis-tooltip');
    if (!tooltip) {
        tooltip = document.createElement('div');
        tooltip.setAttribute('id', 'simply-ellipsis-tooltip');
        document.body.append(tooltip);
    }
    tooltip.setAttribute('ell-value', content);
    tooltip.style.cssText = cssTextString;
    // 根据实际的ell提示框位置来设置气泡框小三角的朝向
    ellArr.forEach((item) => {
        tooltip.classList.remove('has-ell-' + item.type);
    });
    tooltip.classList.add('has-ell-' + type);
    tooltip.classList.add('has-ell');
    tooltip.classList.add('has-ell-visibility');
}
export const setEll = function () {
    ellArr.forEach((item) => {
        document.querySelectorAll(item.class).forEach((dom) => {
            if (isOverFlow(dom)) {
                setEllAction(dom, item.type);
            }
        });
    });
    ellAlwaysArr.forEach((item) => {
        document.querySelectorAll(item.class).forEach((dom) => {
            setEllAction(dom, item.type);
        });
    });
    ellMultipleArr.forEach((item) => {
        document.querySelectorAll(item.class).forEach((dom) => {
            if (dom.scrollHeight > dom.offsetHeight) {
                setEllAction(dom, item.type);
            }
        });
    });
};
function isOverFlow(dom) {
    if (dom.scrollWidth > dom.offsetWidth) {
        return true;
    }
    const domStyle = document.defaultView.getComputedStyle(dom, '');
    const padding = parseInt(domStyle.paddingLeft || 0) + parseInt(domStyle.paddingRight || 0);
    const range = document.createRange();
    range.setStart(dom, 0);
    range.setEnd(dom, dom.childNodes.length);
    const rangeWidth = range.getBoundingClientRect().width;
    return rangeWidth + padding > dom.offsetWidth;
}
function setEllAction(dom, type) {
    // 获取浏览器信息，并转小写
    let userAgent = navigator.userAgent.toLowerCase();
    // 用 test 匹配浏览器信息
    if (/ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(userAgent)) {
        dom.ontouchstart = (e) => {
            e.preventDefault();
            setEllItem(dom, type);
        };
        dom.ontouchend = (e) => {
            e.preventDefault();
            let tooltip = document.getElementById('simply-ellipsis-tooltip');
            if (tooltip) {
                tooltip.classList.remove('has-ell-visibility');
            }
        };
        dom.touchcancel = (e) => {
            e.preventDefault();
            let tooltip = document.getElementById('simply-ellipsis-tooltip');
            if (tooltip) {
                tooltip.classList.remove('has-ell-visibility');
            }
        };
    }
    else {
        dom.onmouseover = () => {
            setEllItem(dom, type);
        };
        dom.onmouseleave = () => {
            let tooltip = document.getElementById('simply-ellipsis-tooltip');
            if (tooltip) {
                tooltip.classList.remove('has-ell-visibility');
            }
        };
    }
}
